﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;

namespace YJKGridTopologyCal.EdgeGraph
{
	public class EdgeGraph
	{
		protected virtual HalfEdge CreateEdge(Coordinate orig)
		{
			return new HalfEdge(orig);
		}

		private HalfEdge Create(Coordinate p0, Coordinate p1)
		{
			HalfEdge halfEdge = this.CreateEdge(p0);
			HalfEdge e = this.CreateEdge(p1);
			HalfEdge.Init(halfEdge, e);
			return halfEdge;
		}

		public virtual HalfEdge AddEdge(Coordinate orig, Coordinate dest)
		{
			if (!EdgeGraph.IsValidEdge(orig, dest))
			{
				return null;
			}
			HalfEdge halfEdge;
			bool flag = this.vertexMap.TryGetValue(orig, out halfEdge);
			HalfEdge halfEdge2 = null;
			if (flag)
			{
				halfEdge2 = halfEdge.Find(dest);
			}
			if (halfEdge2 != null)
			{
				return halfEdge2;
			}
			return this.Insert(orig, dest, halfEdge);
		}

		public static bool IsValidEdge(Coordinate orig, Coordinate dest)
		{
			return dest.CompareTo(orig) != 0;
		}

		private HalfEdge Insert(Coordinate orig, Coordinate dest, HalfEdge eAdj)
		{
			HalfEdge halfEdge = this.Create(orig, dest);
			if (eAdj != null)
			{
				eAdj.Insert(halfEdge);
			}
			else
			{
				this.vertexMap.Add(orig, halfEdge);
			}
			HalfEdge halfEdge2;
			bool flag = this.vertexMap.TryGetValue(dest, out halfEdge2);
			HalfEdge sym = halfEdge.Sym;
			if (flag)
			{
				halfEdge2.Insert(sym);
			}
			else
			{
				this.vertexMap.Add(dest, sym);
			}
			return halfEdge;
		}

		public IEnumerable<HalfEdge> GetVertexEdges()
		{
			return this.vertexMap.Values;
		}

		public HalfEdge FindEdge(Coordinate orig, Coordinate dest)
		{
			HalfEdge halfEdge = this.vertexMap[orig];
			if (halfEdge != null)
			{
				return halfEdge.Find(dest);
			}
			return null;
		}

		private readonly IDictionary<Coordinate, HalfEdge> vertexMap = new Dictionary<Coordinate, HalfEdge>();
	}
}
